﻿using Maltose.Log;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Security.Cryptography.Xml;
using System.Text;

namespace Maltose.MessageQueue.Subscibe
{
    /// <summary>
    /// 消息队列订阅
    /// </summary>
    public class MessageQueueSubscibe : MessageQueueHost
    {
        /// <summary>
        /// 事件参数
        /// </summary>
        /// <param name="args">订单模板内容参数</param>
        /// <param name="deliveryTag">用于确定消费者的tag</param>
        /// <param name="message">原始消息数据</param>
        public delegate void ReceivedEventHandler(string args, ulong deliveryTag, string message);

        /// <summary>
        /// 接受事件
        /// </summary>
        public event ReceivedEventHandler OnReceived;

        /// <summary>
        /// 队列名称
        /// </summary>
        public string QueueName { get; set; }

        /// <summary>
        /// 是否自动确定消息 默认false 需要手动确定
        /// </summary>
        public bool AutoAck { get; set; } = false;

        /// <summary>
        /// 消息队列数量 默认=1 确保忙碌不在分发
        /// </summary>
        public ushort PrefetchCount { get; set; } = 1;

        /// <summary>
        /// 消息队列订阅
        /// </summary>
        /// <param name="connect">连接</param>
        public MessageQueueSubscibe(MessageQueueConnect connect) : base(connect)
        {

        }

        /// <summary>
        /// 消息队列订阅
        /// </summary>
        /// <param name="queueName">队列名称</param>
        /// <param name="connect">连接</param>
        public MessageQueueSubscibe(string queueName, MessageQueueConnect connect) : base(connect)
        {
            QueueName = queueName;
        }

        /// <summary>
        /// 确定消息
        /// </summary>
        /// <param name="deliveryTag"></param>
        /// <param name="multiple"></param>
        public void BasicAck(ulong deliveryTag, bool multiple = false)
        {
            Channel.BasicAck(deliveryTag, multiple);
        }

        /// <summary>
        /// 订阅队列消息
        /// </summary>

        public void Subscibe()
        {
            //声明队列
            string queueName = QueueName;

            Channel.QueueDeclare(queueName, true, false, false, null);

            //公平分发
            Channel.BasicQos(prefetchSize: 0, prefetchCount: PrefetchCount, global: false);

            var eventingBasic = new EventingBasicConsumer(Channel);
            eventingBasic.Received += EventingBasic_Received;
            Channel.BasicConsume(queue: queueName, autoAck: AutoAck, consumer: eventingBasic);
        }

        /// <summary>
        /// 接受事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void EventingBasic_Received(object sender, BasicDeliverEventArgs e)
        {
            var message = Encoding.UTF8.GetString(e.Body.ToArray());
            try
            {
                OnReceived?.Invoke(message, e.DeliveryTag, message);
            }
            catch (Exception ex)
            {
                UseLog.Debug("数据转换错误", "消息队列订阅", ex);
            }

        }
    }
}
